package com.ug.common.ratelimit.implementation;

import cn.hutool.cache.impl.LRUCache;
import com.google.common.util.concurrent.RateLimiter;
import com.ug.common.enums.ErrorCode;
import com.ug.common.exception.SystemException;
import com.ug.common.ratelimit.RateLimit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * @Author LY
 * @create 2024/8/6 15:13
 * @Description guava限流器实现
 */
@Component
public class GuavaRateLimiter extends AbstractRateLimiter {

    private static final Logger logger = LoggerFactory.getLogger(GuavaRateLimiter.class);

    /**
     * 最近最久未使用-LRUCache
     */
    private final LRUCache<String, RateLimiter> cache = new LRUCache<>(4096);

    @Override
    public void check(RateLimit rateLimit) {
        logger.info("Guava限流");
        String combinedKey = rateLimit.limitType().generateCombinedKey(rateLimit);

        RateLimiter rateLimiter = cache.get(combinedKey, () -> RateLimiter.create((double) rateLimit.maxCount() / rateLimit.time()));

        if (!rateLimiter.tryAcquire()) {
            throw new SystemException(ErrorCode.COMMON_REQUEST_TOO_OFTEN);
        }
        logger.info("限制请求key:{}, combined key:{}", rateLimit.key(), combinedKey);
    }
}
